From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- .../Chipset/LynxPoint/AcpiTables/Dsdt/Pch.asl | 977 ++++++ .../LynxPoint/AcpiTables/Dsdt/PchAcpiTables.cif | 19 + .../LynxPoint/AcpiTables/Dsdt/PchAcpiTables.inf | 53 + .../LynxPoint/AcpiTables/Dsdt/PchAcpiTables.sdl | 735 +++++ .../Chipset/LynxPoint/AcpiTables/Dsdt/PchAudio.asl | 44 + .../LynxPoint/AcpiTables/Dsdt/PchAudioDsp.asl | 133 + .../Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci1.asl | 238 ++ .../Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci2.asl | 199 ++ .../Chipset/LynxPoint/AcpiTables/Dsdt/PchPcie.asl | 288 ++ .../LynxPoint/AcpiTables/Dsdt/PchSerialIo.asl | 1029 ++++++ .../Chipset/LynxPoint/AcpiTables/Dsdt/PchSmb.asl | 605 ++++ .../Chipset/LynxPoint/AcpiTables/Dsdt/PchXhci.asl | 1229 +++++++ .../Chipset/LynxPoint/AcpiTables/Dsdt/UsbSbd.asl | 92 + .../Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.c | 292 ++ .../LynxPoint/ActiveBios/Dxe/ActiveBios.cif | 14 + .../Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.h | 104 + .../LynxPoint/ActiveBios/Dxe/ActiveBios.inf | 77 + .../LynxPoint/ActiveBios/Dxe/ActiveBios.mak | 96 + .../LynxPoint/ActiveBios/Dxe/ActiveBios.sdl | 67 + .../LynxPoint/ActiveBios/Dxe/ActiveBiosDepex.dxs | 39 + .../LynxPoint/ActiveBios/Dxe/ActiveBiosMain.c | 73 + .../LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.c | 28 + .../LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.h | 62 + .../Chipset/LynxPoint/Guid/PchGuidLib.cif | 14 + .../Chipset/LynxPoint/Guid/PchGuidLib.inf | 48 + .../Chipset/LynxPoint/Guid/PchGuidLib.mak | 21 + .../Chipset/LynxPoint/Guid/PchGuidLib.sdl | 43 + .../LynxPoint/Guid/S3SupportHob/S3SupportHob.c | 30 + .../LynxPoint/Guid/S3SupportHob/S3SupportHob.h | 73 + .../Chipset/LynxPoint/Include/IntelPchDxe.dsc | 58 + .../Chipset/LynxPoint/Include/IntelPchDxeLib.dsc | 30 + .../Chipset/LynxPoint/Include/IntelPchInclude.cif | 33 + .../Chipset/LynxPoint/Include/IntelPchInclude.sdl | 56 + .../Chipset/LynxPoint/Include/IntelPchPei.dsc | 38 + .../Chipset/LynxPoint/Include/IntelPchPeiLib.dsc | 28 + .../Chipset/LynxPoint/Include/IobpDefinitions.h | 51 + .../Include/Library/DxeRuntimePciLibPciExpress.h | 61 + .../Include/Library/PchPciExpressHelpersLib.h | 296 ++ .../LynxPoint/Include/Library/PchPlatformLib.h | 385 +++ .../LynxPoint/Include/Library/PchSmbusLibrary.h | 44 + .../LynxPoint/Include/Library/RcFviDxeLib.h | 175 + .../Chipset/LynxPoint/Include/PchAccess.h | 509 +++ ReferenceCode/Chipset/LynxPoint/Include/PchRegs.h | 474 +++ .../LynxPoint/Include/PchRegs/PchRegsAdsp.h | 109 + .../Chipset/LynxPoint/Include/PchRegs/PchRegsHda.h | 399 +++ .../Chipset/LynxPoint/Include/PchRegs/PchRegsLan.h | 196 ++ .../Chipset/LynxPoint/Include/PchRegs/PchRegsLpc.h | 1018 ++++++ .../LynxPoint/Include/PchRegs/PchRegsPcie.h | 548 ++++ .../LynxPoint/Include/PchRegs/PchRegsRcrb.h | 483 +++ .../LynxPoint/Include/PchRegs/PchRegsSata.h | 703 ++++ .../LynxPoint/Include/PchRegs/PchRegsSerialIo.h | 169 + .../LynxPoint/Include/PchRegs/PchRegsSmbus.h | 172 + .../Chipset/LynxPoint/Include/PchRegs/PchRegsSpi.h | 380 +++ .../LynxPoint/Include/PchRegs/PchRegsThermal.h | 100 + .../Chipset/LynxPoint/Include/PchRegs/PchRegsUsb.h | 563 ++++ .../Chipset/LynxPoint/Include/PchUsbConfig.h | 178 + .../Chipset/LynxPoint/IoTrap/Smm/IoTrap.c | 884 +++++ .../Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif | 13 + .../Chipset/LynxPoint/IoTrap/Smm/IoTrap.h | 221 ++ .../Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf | 92 + .../Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak | 118 + .../Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl | 67 + .../Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs | 43 + .../LegacyInterrupt/Dxe/IntelLegacyInterrupt.cif | 12 + .../LegacyInterrupt/Dxe/IntelLegacyInterrupt.mak | 91 + .../LegacyInterrupt/Dxe/IntelLegacyInterrupt.sdl | 67 + .../LegacyInterrupt/Dxe/LegacyInterrupt.c | 204 ++ .../LegacyInterrupt/Dxe/LegacyInterrupt.h | 119 + .../LegacyInterrupt/Dxe/LegacyInterrupt.inf | 73 + .../DxeRuntimePciLibPciExpress.c | 2148 +++++++++++++ .../DxeRuntimePciLibPciExpress.cif | 11 + .../DxeRuntimePciLibPciExpress.inf | 78 + .../DxeRuntimePciLibPciExpress.mak | 76 + .../DxeRuntimePciLibPciExpress.sdl | 72 + ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif | 14 + ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl | 55 + .../PchPciExpressHelpersLib.cif | 12 + .../PchPciExpressHelpersLib.inf | 66 + .../PchPciExpressHelpersLib.mak | 88 + .../PchPciExpressHelpersLib.sdl | 83 + .../PchPciExpressHelpersLibrary.c | 2201 +++++++++++++ .../PchPciExpressHelpersLibrary.h | 42 + .../LynxPoint/Library/PchPlatformLib/IobpAccess.c | 295 ++ .../Library/PchPlatformLib/PchPlatformLib.cif | 13 + .../Library/PchPlatformLib/PchPlatformLib.inf | 67 + .../Library/PchPlatformLib/PchPlatformLib.mak | 112 + .../Library/PchPlatformLib/PchPlatformLib.sdl | 93 + .../Library/PchPlatformLib/PchPlatformLibrary.c | 831 +++++ .../Library/PchPlatformLib/PchPlatformLibrary.h | 29 + .../Library/PchSmbusLib/Common/PchSmbusComLib.cif | 8 + .../Library/PchSmbusLib/Common/PchSmbusLib.c | 54 + .../Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif | 9 + .../Library/PchSmbusLib/Dxe/PchSmbusLib.h | 25 + .../Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf | 63 + .../LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif | 14 + .../LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak | 74 + .../LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl | 59 + .../Library/PchSmbusLib/Pei/PchSmbusLib.h | 25 + .../Library/PchSmbusLib/Pei/PchSmbusLibPei.inf | 64 + .../Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif | 9 + .../Library/RcFviDxeLib/CreateFviLibrary.c | 225 ++ .../LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif | 12 + .../LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf | 67 + .../LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak | 69 + .../LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl | 73 + .../LynxPoint/Library/RcFviDxeLib/RcFviLib.h | 49 + ReferenceCode/Chipset/LynxPoint/LynxPoint.cif | 47 + ReferenceCode/Chipset/LynxPoint/Pch.sdl | 485 +++ .../Chipset/LynxPoint/PchInit/Common/PchHSIO.c | 48 + .../Chipset/LynxPoint/PchInit/Common/PchHSIO.h | 47 + .../LynxPoint/PchInit/Common/PchHSIOLptHB0.c | 295 ++ .../LynxPoint/PchInit/Common/PchHSIOLptHB0.h | 44 + .../LynxPoint/PchInit/Common/PchHsioLptHCx.c | 326 ++ .../LynxPoint/PchInit/Common/PchHsioLptHCx.h | 47 + .../LynxPoint/PchInit/Common/PchHsioLptLpBx.c | 239 ++ .../LynxPoint/PchInit/Common/PchHsioLptLpBx.h | 42 + .../Chipset/LynxPoint/PchInit/Common/PchInitVar.c | 31 + .../Chipset/LynxPoint/PchInit/Common/PchInitVar.h | 65 + .../LynxPoint/PchInit/Common/PchUsbCommon.c | 3032 +++++++++++++++++ .../LynxPoint/PchInit/Common/PchUsbCommon.h | 360 +++ .../LynxPoint/PchInit/Common/PchUsbCommonLib.cif | 21 + .../LynxPoint/PchInit/Common/PchUsbCommonLib.mak | 127 + .../LynxPoint/PchInit/Common/PchUsbCommonLib.sdl | 81 + .../Chipset/LynxPoint/PchInit/Dxe/PchAudioDsp.c | 602 ++++ .../Chipset/LynxPoint/PchInit/Dxe/PchAzalia.c | 915 ++++++ .../Chipset/LynxPoint/PchInit/Dxe/PchDebugDump.c | 330 ++ .../Chipset/LynxPoint/PchInit/Dxe/PchFvi.c | 137 + .../Chipset/LynxPoint/PchInit/Dxe/PchInit.c | 2469 ++++++++++++++ .../Chipset/LynxPoint/PchInit/Dxe/PchInit.dxs | 48 + .../Chipset/LynxPoint/PchInit/Dxe/PchInit.h | 653 ++++ .../Chipset/LynxPoint/PchInit/Dxe/PchInitCommon.h | 110 + .../Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.cif | 28 + .../Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.inf | 134 + .../Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.mak | 150 + .../Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.sdl | 66 + .../Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c | 134 + .../Chipset/LynxPoint/PchInit/Dxe/PchLan.c | 152 + .../Chipset/LynxPoint/PchInit/Dxe/PchMisc.c | 395 +++ .../Chipset/LynxPoint/PchInit/Dxe/PchPm.c | 3389 ++++++++++++++++++++ .../Chipset/LynxPoint/PchInit/Dxe/PchRootPorts.c | 2154 +++++++++++++ .../Chipset/LynxPoint/PchInit/Dxe/PchSata.c | 1547 +++++++++ .../Chipset/LynxPoint/PchInit/Dxe/PchSerialIo.c | 997 ++++++ .../Chipset/LynxPoint/PchInit/Dxe/PchUsb.c | 439 +++ .../LynxPoint/PchInit/Dxe/PchUsbPrecondition.c | 522 +++ .../LynxPoint/PchInit/Dxe/PchUsbPrecondition.h | 54 + .../Chipset/LynxPoint/PchInit/Pei/PchDmiPeim.c | 831 +++++ .../Chipset/LynxPoint/PchInit/Pei/PchInitCommon.h | 73 + .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.c | 2232 +++++++++++++ .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.cif | 17 + .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.dxs | 39 + .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.h | 253 ++ .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.inf | 108 + .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.mak | 117 + .../Chipset/LynxPoint/PchInit/Pei/PchInitPeim.sdl | 67 + .../Chipset/LynxPoint/PchInit/Pei/PchUsbInit.c | 198 ++ .../LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c | 105 + .../Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c | 753 +++++ .../LynxPoint/PchInit/Smm/PchLateInitSmm.cif | 13 + .../LynxPoint/PchInit/Smm/PchLateInitSmm.dxs | 46 + .../Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h | 106 + .../LynxPoint/PchInit/Smm/PchLateInitSmm.inf | 88 + .../LynxPoint/PchInit/Smm/PchLateInitSmm.mak | 97 + .../LynxPoint/PchInit/Smm/PchLateInitSmm.sdl | 71 + .../PchSmiDispatcher/Smm/PchSmiDispatcher.cif | 24 + .../PchSmiDispatcher/Smm/PchSmiDispatcher.dxs | 43 + .../PchSmiDispatcher/Smm/PchSmiDispatcher.inf | 104 + .../PchSmiDispatcher/Smm/PchSmiDispatcher.mak | 115 + .../PchSmiDispatcher/Smm/PchSmiDispatcher.sdl | 102 + .../LynxPoint/PchSmiDispatcher/Smm/PchSmm.h | 727 +++++ .../LynxPoint/PchSmiDispatcher/Smm/PchSmmCore.c | 891 +++++ .../LynxPoint/PchSmiDispatcher/Smm/PchSmmGpi.c | 101 + .../LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.c | 317 ++ .../LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.h | 155 + .../LynxPoint/PchSmiDispatcher/Smm/PchSmmIchn.c | 2425 ++++++++++++++ .../PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c | 519 +++ .../PchSmiDispatcher/Smm/PchSmmPowerButton.c | 104 + .../LynxPoint/PchSmiDispatcher/Smm/PchSmmSw.c | 87 + .../LynxPoint/PchSmiDispatcher/Smm/PchSmmSx.c | 975 ++++++ .../LynxPoint/PchSmiDispatcher/Smm/PchSmmUsb.c | 300 ++ .../PchSmiDispatcher/Smm/PchxSmmHelpers.c | 820 +++++ .../PchSmiDispatcher/Smm/PchxSmmHelpers.h | 128 + .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.c | 388 +++ .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.cif | 13 + .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.dxs | 52 + .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.h | 99 + .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.inf | 86 + .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.mak | 100 + .../Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.sdl | 69 + .../Chipset/LynxPoint/Ppi/IntelPchPpiLib.cif | 28 + .../Chipset/LynxPoint/Ppi/IntelPchPpiLib.inf | 68 + .../Chipset/LynxPoint/Ppi/IntelPchPpiLib.mak | 63 + .../Chipset/LynxPoint/Ppi/IntelPchPpiLib.sdl | 72 + .../LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.c | 43 + .../LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.h | 80 + .../Chipset/LynxPoint/Ppi/PchInit/PchInit.c | 43 + .../Chipset/LynxPoint/Ppi/PchInit/PchInit.h | 153 + .../LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.c | 47 + .../LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.h | 53 + .../Ppi/PchPlatformPolicy/PchPlatformPolicy.c | 43 + .../Ppi/PchPlatformPolicy/PchPlatformPolicy.h | 263 ++ .../Chipset/LynxPoint/Ppi/PchReset/PchReset.c | 42 + .../Chipset/LynxPoint/Ppi/PchReset/PchReset.h | 68 + .../LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.c | 45 + .../LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.h | 126 + .../Chipset/LynxPoint/Ppi/SmmControl/SmmControl.c | 26 + .../Chipset/LynxPoint/Ppi/SmmControl/SmmControl.h | 72 + ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.c | 44 + ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.h | 57 + ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.c | 32 + ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.h | 53 + .../LynxPoint/Protocol/ActiveBios/ActiveBios.c | 47 + .../LynxPoint/Protocol/ActiveBios/ActiveBios.h | 136 + .../LynxPoint/Protocol/IntelPchProtocolLib.cif | 33 + .../LynxPoint/Protocol/IntelPchProtocolLib.inf | 70 + .../LynxPoint/Protocol/IntelPchProtocolLib.mak | 62 + .../LynxPoint/Protocol/IntelPchProtocolLib.sdl | 71 + .../Chipset/LynxPoint/Protocol/PchInfo/PchInfo.c | 41 + .../Chipset/LynxPoint/Protocol/PchInfo/PchInfo.h | 121 + .../Protocol/PchInfo/UsbHcPortPrecondition.h | 53 + .../Protocol/PchPlatformPolicy/PchPlatformPolicy.c | 44 + .../Protocol/PchPlatformPolicy/PchPlatformPolicy.h | 1061 ++++++ .../Chipset/LynxPoint/Protocol/PchReset/PchReset.c | 44 + .../Chipset/LynxPoint/Protocol/PchReset/PchReset.h | 139 + .../LynxPoint/Protocol/PchS3Support/PchS3Support.c | 43 + .../LynxPoint/Protocol/PchS3Support/PchS3Support.h | 218 ++ .../PchSmmIoTrapControl/PchSmmIoTrapControl.c | 42 + .../PchSmmIoTrapControl/PchSmmIoTrapControl.h | 90 + .../LynxPoint/Protocol/SerialGpio/SerialGpio.c | 34 + .../LynxPoint/Protocol/SerialGpio/SerialGpio.h | 166 + .../Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.c | 46 + .../Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.h | 177 + .../Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.c | 42 + .../Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.h | 182 ++ ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.c | 48 + ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.h | 346 ++ ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.c | 34 + ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.h | 157 + .../LynxPoint/Reset/Common/PchResetCommon.c | 254 ++ .../LynxPoint/Reset/Common/PchResetCommon.h | 86 + .../LynxPoint/Reset/Common/PchResetCommonLib.cif | 11 + .../LynxPoint/Reset/Common/PchResetCommonLib.mak | 124 + .../LynxPoint/Reset/Common/PchResetCommonLib.sdl | 97 + .../Chipset/LynxPoint/Reset/Pei/PchReset.c | 134 + .../Chipset/LynxPoint/Reset/Pei/PchReset.dxs | 39 + .../Chipset/LynxPoint/Reset/Pei/PchReset.h | 65 + .../Chipset/LynxPoint/Reset/Pei/PchResetPeim.cif | 13 + .../Chipset/LynxPoint/Reset/Pei/PchResetPeim.inf | 84 + .../Chipset/LynxPoint/Reset/Pei/PchResetPeim.mak | 99 + .../Chipset/LynxPoint/Reset/Pei/PchResetPeim.sdl | 67 + .../Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.c | 496 +++ .../LynxPoint/Reset/RuntimeDxe/PchReset.cif | 13 + .../LynxPoint/Reset/RuntimeDxe/PchReset.dxs | 39 + .../Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.h | 83 + .../LynxPoint/Reset/RuntimeDxe/PchReset.mak | 117 + .../LynxPoint/Reset/RuntimeDxe/PchReset.sdl | 67 + .../LynxPoint/Reset/RuntimeDxe/PchResetRuntime.inf | 90 + .../Chipset/LynxPoint/S3Support/Dxe/PchS3Support.c | 369 +++ .../LynxPoint/S3Support/Dxe/PchS3Support.cif | 13 + .../LynxPoint/S3Support/Dxe/PchS3Support.dxs | 45 + .../Chipset/LynxPoint/S3Support/Dxe/PchS3Support.h | 126 + .../LynxPoint/S3Support/Dxe/PchS3Support.inf | 103 + .../LynxPoint/S3Support/Dxe/PchS3Support.mak | 115 + .../LynxPoint/S3Support/Dxe/PchS3Support.sdl | 75 + .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.c | 563 ++++ .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.cif | 13 + .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.dxs | 41 + .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.h | 106 + .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.inf | 100 + .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.mak | 52 + .../Chipset/LynxPoint/S3Support/Pei/PchS3Peim.sdl | 75 + .../Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.c | 156 + .../LynxPoint/S3Support/Smm/S3SupportSmm.cif | 13 + .../LynxPoint/S3Support/Smm/S3SupportSmm.dxs | 46 + .../Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.h | 60 + .../LynxPoint/S3Support/Smm/S3SupportSmm.inf | 95 + .../LynxPoint/S3Support/Smm/S3SupportSmm.mak | 94 + .../LynxPoint/S3Support/Smm/S3SupportSmm.sdl | 57 + .../SampleCode/AcpiTables/Dsdt/Sensor.asl | 103 + .../SampleCode/AcpiTables/Dsdt/SerialIoDevices.asl | 1527 +++++++++ .../BiosWriteProtect/Smm/PchBiosWriteProtect.c | 188 ++ .../BiosWriteProtect/Smm/PchBiosWriteProtect.dxs | 48 + .../BiosWriteProtect/Smm/PchBiosWriteProtect.h | 36 + .../BiosWriteProtect/Smm/PchBiosWriteProtect.inf | 94 + .../SampleCode/Guid/SmbusArpMap/SmbusArpMap.h | 29 + .../Chipset/LynxPoint/SampleCode/Include/Acpi3_0.h | 681 ++++ .../LynxPoint/SampleCode/Include/PchAslUpdateLib.h | 166 + .../Library/AslUpdate/Dxe/PchAslUpdateLib.c | 474 +++ .../Library/AslUpdate/Dxe/PchAslUpdateLib.cif | 11 + .../Library/AslUpdate/Dxe/PchAslUpdateLib.inf | 66 + .../Library/AslUpdate/Dxe/PchAslUpdateLib.mak | 83 + .../Library/AslUpdate/Dxe/PchAslUpdateLib.sdl | 29 + .../PchPolicyInit/Common/PchPolicyInitCommon.c | 427 +++ .../PchPolicyInit/Common/PchPolicyInitCommon.h | 33 + .../PchPolicyInit/Dxe/PchPolicyInitDxe.c | 490 +++ .../PchPolicyInit/Dxe/PchPolicyInitDxe.dxs | 44 + .../PchPolicyInit/Dxe/PchPolicyInitDxe.h | 56 + .../PchPolicyInit/Dxe/PchPolicyInitDxe.inf | 82 + .../PchPolicyInit/Pei/PchPolicyInitPei.c | 250 ++ .../PchPolicyInit/Pei/PchPolicyInitPei.dxs | 40 + .../PchPolicyInit/Pei/PchPolicyInitPei.h | 60 + .../PchPolicyInit/Pei/PchPolicyInitPei.inf | 87 + .../Chipset/LynxPoint/SampleCode/PchSampleCode.cif | 34 + .../SampleCode/Ppi/IntelPchSampleCodePpiLib.inf | 45 + .../SampleCode/Ppi/SmbusPolicy/SmbusPolicy.h | 38 + .../LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.c | 25 + .../LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.h | 136 + .../SampleCode/Ppi/UsbController/UsbController.h | 49 + .../SampleCode/Protocol/SmmSmbus/SmmSmbus.h | 50 + .../LynxPoint/SataController/Dxe/SataController.c | 943 ++++++ .../SataController/Dxe/SataController.cif | 13 + .../LynxPoint/SataController/Dxe/SataController.h | 323 ++ .../SataController/Dxe/SataController.inf | 94 + .../SataController/Dxe/SataController.mak | 116 + .../SataController/Dxe/SataController.sdl | 67 + .../SataController/Dxe/SataControllerName.c | 173 + .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.c | 516 +++ .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif | 13 + .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs | 39 + .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.h | 193 ++ .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf | 79 + .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak | 96 + .../LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl | 67 + .../Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.c | 523 +++ .../LynxPoint/SmartTimer/Dxe/SmartTimer.cif | 13 + .../LynxPoint/SmartTimer/Dxe/SmartTimer.dxs | 42 + .../Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.h | 178 + .../LynxPoint/SmartTimer/Dxe/SmartTimer.inf | 77 + .../LynxPoint/SmartTimer/Dxe/SmartTimer.mak | 100 + .../LynxPoint/SmartTimer/Dxe/SmartTimer.sdl | 76 + .../LynxPoint/Smbus/Common/PchSmbusCommon.h | 190 ++ .../LynxPoint/Smbus/Common/PchSmbusCommonLib.cif | 11 + .../LynxPoint/Smbus/Common/PchSmbusCommonLib.mak | 124 + .../LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl | 92 + .../Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c | 661 ++++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs | 40 + .../Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h | 360 +++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c | 681 ++++ .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif | 14 + .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf | 93 + .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak | 103 + .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl | 67 + .../Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c | 149 + .../Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs | 44 + .../Chipset/LynxPoint/Smbus/Pei/PchSmbus.h | 409 +++ .../Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c | 444 +++ .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif | 14 + .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf | 88 + .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak | 97 + .../LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl | 67 + .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c | 291 ++ .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif | 15 + .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf | 91 + .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak | 97 + .../LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl | 67 + .../LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c | 117 + .../Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c | 241 ++ .../Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs | 41 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbus.h | 183 ++ .../LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c | 103 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c | 128 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif | 14 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf | 95 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak | 105 + .../Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl | 67 + .../LynxPoint/SmmControl/Pei/PeiSmmControl.cif | 13 + .../LynxPoint/SmmControl/Pei/PeiSmmControl.mak | 93 + .../LynxPoint/SmmControl/Pei/PeiSmmControl.sdl | 24 + .../LynxPoint/SmmControl/Pei/SmmControl.dxs | 35 + .../LynxPoint/SmmControl/Pei/SmmControl.inf | 76 + .../LynxPoint/SmmControl/Pei/SmmControlDriver.c | 282 ++ .../LynxPoint/SmmControl/Pei/SmmControlDriver.h | 95 + .../LynxPoint/SmmControl/RuntimeDxe/SmmControl.cif | 13 + .../LynxPoint/SmmControl/RuntimeDxe/SmmControl.dxs | 36 + .../LynxPoint/SmmControl/RuntimeDxe/SmmControl.inf | 85 + .../LynxPoint/SmmControl/RuntimeDxe/SmmControl.mak | 105 + .../LynxPoint/SmmControl/RuntimeDxe/SmmControl.sdl | 67 + .../SmmControl/RuntimeDxe/SmmControlDriver.c | 478 +++ .../SmmControl/RuntimeDxe/SmmControlDriver.h | 164 + .../LynxPoint/Spi/Common/PchSpiCommonLib.cif | 11 + .../LynxPoint/Spi/Common/PchSpiCommonLib.mak | 125 + .../LynxPoint/Spi/Common/PchSpiCommonLib.sdl | 92 + .../Chipset/LynxPoint/Spi/Common/SpiCommon.c | 1425 ++++++++ .../Chipset/LynxPoint/Spi/Common/SpiCommon.h | 300 ++ ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.c | 133 + ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.dxs | 39 + ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.h | 74 + .../Chipset/LynxPoint/Spi/Pei/PchSpiPeim.cif | 13 + .../Chipset/LynxPoint/Spi/Pei/PchSpiPeim.inf | 83 + .../Chipset/LynxPoint/Spi/Pei/PchSpiPeim.mak | 99 + .../Chipset/LynxPoint/Spi/Pei/PchSpiPeim.sdl | 67 + .../Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.c | 322 ++ .../Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.dxs | 39 + .../Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.h | 92 + .../LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.cif | 13 + .../LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.inf | 91 + .../LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.mak | 113 + .../LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.sdl | 66 + ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.c | 244 ++ ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.dxs | 45 + ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.h | 76 + .../Chipset/LynxPoint/Spi/Smm/PchSpiSmm.cif | 13 + .../Chipset/LynxPoint/Spi/Smm/PchSpiSmm.inf | 92 + .../Chipset/LynxPoint/Spi/Smm/PchSpiSmm.mak | 112 + .../Chipset/LynxPoint/Spi/Smm/PchSpiSmm.sdl | 66 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.c | 229 ++ ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.h | 82 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.c | 77 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.cif | 15 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.dxs | 45 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.h | 47 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.inf | 87 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.mak | 111 + ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.sdl | 66 + .../Chipset/LynxPoint/Wdt/Common/WdtCommon.c | 246 ++ .../Chipset/LynxPoint/Wdt/Common/WdtCommon.h | 166 + .../Chipset/LynxPoint/Wdt/Common/WdtCommonLib.cif | 11 + .../Chipset/LynxPoint/Wdt/Common/WdtCommonLib.mak | 103 + .../Chipset/LynxPoint/Wdt/Common/WdtCommonLib.sdl | 92 + ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.c | 218 ++ ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.cif | 12 + ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.dxs | 30 + ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.inf | 87 + ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.mak | 102 + ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.sdl | 68 + ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.c | 280 ++ ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.cif | 12 + ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.dxs | 31 + ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.mak | 94 + ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.sdl | 78 + .../Chipset/LynxPoint/Wdt/Pei/WdtPeim.inf | 87 + ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.cif | 12 + ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.sdl | 73 + 432 files changed, 89947 insertions(+) create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/Pch.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudio.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudioDsp.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci1.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci2.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchPcie.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSerialIo.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSmb.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchXhci.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/UsbSbd.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.c create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.h create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosDepex.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosMain.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxe.dsc create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxeLib.dsc create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IntelPchPei.dsc create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IntelPchPeiLib.dsc create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/IobpDefinitions.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/Library/DxeRuntimePciLibPciExpress.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/Library/PchPciExpressHelpersLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/Library/PchPlatformLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/Library/PchSmbusLibrary.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/Library/RcFviDxeLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchAccess.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsAdsp.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsHda.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLan.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLpc.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsPcie.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsRcrb.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSata.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSerialIo.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSpi.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsThermal.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsUsb.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Include/PchUsbConfig.h create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.c create mode 100644 ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.h create mode 100644 ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/LynxPoint.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Pch.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAudioDsp.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAzalia.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchDebugDump.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchFvi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchLan.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchMisc.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchPm.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchRootPorts.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSerialIo.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsb.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchDmiPeim.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbInit.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmm.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmCore.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmGpi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.h create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmIchn.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPowerButton.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSw.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSx.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmUsb.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.c create mode 100644 ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/UsbHcPortPrecondition.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchResetRuntime.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.c create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.h create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.c create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.h create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.c create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.h create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/Sensor.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/SerialIoDevices.asl create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Guid/SmbusArpMap/SmbusArpMap.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Include/Acpi3_0.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Include/PchAslUpdateLib.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/PchSampleCode.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/IntelPchSampleCodePpiLib.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmbusPolicy/SmbusPolicy.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/UsbController/UsbController.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SampleCode/Protocol/SmmSmbus/SmmSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataControllerName.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.h create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.c create mode 100644 ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.h create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.c create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.dxs create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.mak create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.sdl create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPeim.inf create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.cif create mode 100644 ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.sdl (limited to 'ReferenceCode/Chipset/LynxPoint') 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 +#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 @@ + + 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" + 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_CPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_CPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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__" in register/bit names. e.g., "_PCH_LPT_" + - Registers / bits that are different between SKUs are denoted by "_" + 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 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 @@ + + 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" + 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 @@ + + name = "IntelLegacyInterrupt" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\LegacyInterrupt\Dxe" + RefName = "IntelLegacyInterrupt" +[files] +"IntelLegacyInterrupt.sdl" +"IntelLegacyInterrupt.mak" +"LegacyInterrupt.c" +"LegacyInterrupt.h" +"LegacyInterrupt.inf" + 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 @@ + + name = "DxeRuntimePciLibPciExpress" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\DxeRuntimePciLibPciExpress" + RefName = "DxeRuntimePciLibPciExpress" +[files] +"DxeRuntimePciLibPciExpress.sdl" +"DxeRuntimePciLibPciExpress.mak" +"DxeRuntimePciLibPciExpress.c" +"DxeRuntimePciLibPciExpress.inf" + 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 @@ + + name = "PchLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\" + RefName = "PchLib" +[files] +"PchLib.sdl" +[parts] +"DxeRuntimePciLibPciExpress" +"PchPciExpressHelpersLib" +"PchPlatformLib" +"PchSmbusLib" +"RcFviDxeLib" + 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 @@ + + name = "PchPciExpressHelpersLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchPciExpressHelpersLib" + RefName = "PchPciExpressHelpersLib" +[files] +"PchPciExpressHelpersLib.sdl" +"PchPciExpressHelpersLib.mak" +"PchPciExpressHelpersLibrary.c" +"PchPciExpressHelpersLibrary.h" +"PchPciExpressHelpersLib.inf" + 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 @@ + + 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" + 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 @@ + + name = "PchSmbusComLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Common\" + RefName = "PchSmbusComLib" +[files] +"PchSmbusLib.c" + 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 @@ + + name = "PchSmbusDxeLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Dxe\" + RefName = "PchSmbusDxeLib" +[files] +"PchSmbusLib.h" +"PchSmbusLibDxe.inf" + 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 @@ + + 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" + 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 @@ + + name = "PchSmbusPeiLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Pei\" + RefName = "PchSmbusPeiLib" +[files] +"PchSmbusLib.h" +"PchSmbusLibPei.inf" + 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 @@ + + name = "RcFviDxeLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\RcFviDxeLib" + RefName = "RcFviDxeLib" +[files] +"RcFviDxeLib.sdl" +"RcFviDxeLib.mak" +"CreateFviLibrary.c" +"RcFviLib.h" +"RcFviDxeLib.inf" + 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 @@ + + 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" + \ 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 @@ + + 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" + 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 @@ + + 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" + 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; iSerialIoConfig->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; iSerialIoConfig->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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 + +/// +/// 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 + +/// +/// 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 +/// +/// 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 @@ + + 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" + 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 @@ + + name = "PchResetCommonLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Reset\Common" + RefName = "PchResetCommonLib" +[files] +"PchResetCommonLib.sdl" +"PchResetCommonLib.mak" +"PchResetCommon.h" +"PchResetCommon.c" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + \ 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 @@ + + 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" + \ 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 @@ + + 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" + \ 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 @@ + + name = "PchAslUpdateLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\SampleCode\Library\AslUpdate\Dxe\" + RefName = "PchAslUpdateLib" +[files] +"PchAslUpdateLib.sdl" +"PchAslUpdateLib.mak" +"PchAslUpdateLib.c" +"PchAslUpdateLib.inf" + 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 +# +#********************************************************************** +# +# +# Name: PchAslUpdateLib.mak +# +# Description: +# +# +#********************************************************************** +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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + name = "PchSmbusCommonLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Common" + RefName = "PchSmbusCommonLib" +[files] +"PchSmbusCommonLib.sdl" +"PchSmbusCommonLib.mak" +"PchSmbusExec.c" +"PchSmbusCommon.h" + \ 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 +# +#********************************************************************** +# +# +# Name: PeiSmmControl.mak +# +# Description: +# +# +#********************************************************************** +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 @@ + + 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" + 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 @@ + + name = "PchSpiCommonLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Spi\Common" + RefName = "PchSpiCommonLib" +[files] +"PchSpiCommonLib.sdl" +"PchSpiCommonLib.mak" +"SpiCommon.c" +"SpiCommon.h" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + 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" + 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 @@ + + name = "WdtCommonLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\Common" + RefName = "WdtCommonLib" +[files] +"WdtCommonLib.sdl" +"WdtCommonLib.mak" +"WdtCommon.h" +"WdtCommon.c" + 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 @@ + + name = "WdtDxe" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\Dxe\" + RefName = "WdtDxe" +[files] +"WdtDxe.sdl" +"WdtDxe.dxs" +"WdtDxe.mak" +"WdtDxe.c" +"WdtDxe.inf" + 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 @@ + + name = "WdtPei" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\Pei\" + RefName = "WdtPei" +[files] +"WdtPei.sdl" +"WdtPei.dxs" +"WdtPei.mak" +"WdtPei.c" +"WdtPeim.inf" + 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 @@ + + name = "Wdt" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\" + RefName = "Wdt" +[files] +"Wdt.sdl" +[parts] +"WdtCommonLib" +"WdtDxe" +"WdtPei" + 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 ** +#** ** +#************************************************************************* +#************************************************************************* -- cgit v1.2.3